#!/usr/bin/env python
# encoding: utf-8
"""
# @Time    : 2022/6/12 11:05
# @Author  : 心如潭水静无风
# @Email   : 3148508410@qq.com
# @File    : finally_code.py
# @Software: PyCharm
ps:
1.谷歌浏览器版本：102.0.5005.115(最新版本)
2.chromedriver版本：102.0.5005.273
3.桌面-右键-显示设置-缩放级别改为 100%（不修改验证码识别会出错）
4.考虑到网络及电脑响应速度，程序响应时间设置较长（关键步骤设置为 7秒延时）
5.验证码识别调用超级鹰API，识别次数为100次，已用20次
6.程序运行完成后，查看当前目录下新增course.txt

"""
import os
import time
import requests
from hashlib import md5
from lxml import etree
from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By

# ----------------------------------------自动输入账号密码------------------------------------------------------
# 0.账号密码的操作
username = input('请输入你的明华账号: ')  # 账号
password = input('请输入你的明华密码: ')  # 密码
code = ''  # 验证码
chromedriver = "./chromedriver"
os.environ["webdriver.chrome.driver"] = chromedriver
driver = webdriver.Chrome(chromedriver)  # 模拟打开浏览器
driver.get("https://mooc.yit.edu.cn/user/login")  # 打开网址
driver.maximize_window()  # 窗口最大化（无关紧要哈）

driver.find_element(By.XPATH, '//*[@id="username"]').send_keys(username)  # 自动输入账号

driver.find_element(By.XPATH, '//*[@id="password"]').send_keys(password)  # 自动输入密码

# ----------------------------------------验证码识别↓------------------------------------------------------
# 1.保存验证码到本地
code_img = driver.find_element(By.XPATH, '//*[@id="codeImg"]')  # 验证码图片标签定位
driver.save_screenshot('./code.png')  # 截取当前屏幕
location = code_img.location  # 返回图片x，y坐标，左上角。
size = code_img.size  # 返回验证码图片的高和宽
# 定位到验证码图片的坐标范围，注意电脑显示设置-缩放级别100%
box = (location['x'], location['y'], location['x'] + size['width'], location['y'] + size['height'])
img = Image.open('./code.png')  # 打开刚截取的整张页面
code_path = './code_finally.png'  # 截取到的验证码的图片的路径、名称
frame = img.crop(box)  # 根据指定区域进行图片截取
# frame.show()  # 查看截取的图片
frame.save(code_path)  # 保存截取到的验证码图片
print(location, size)


# 2.调用超级鹰API识别验证码
class Chaojiying_Client(object):
    def __init__(self, username, password, soft_id):
        self.username = username
        password = password.encode('utf8')
        self.password = md5(password).hexdigest()
        self.soft_id = soft_id
        self.base_params = {
            'user': self.username,
            'pass2': self.password,
            'softid': self.soft_id,
        }
        self.headers = {
            'Connection': 'Keep-Alive',
            'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
        }

    def PostPic(self, im, codetype):
        """
        im: 图片字节
        codetype: 题目类型 参考 http://www.chaojiying.com/price.html
        """
        params = {
            'codetype': codetype,
        }
        params.update(self.base_params)
        files = {'userfile': ('ccc.jpg', im)}
        r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files,
                          headers=self.headers)
        return r.json()

    def PostPic_base64(self, base64_str, codetype):
        """
        im: 图片字节
        codetype: 题目类型 参考 http://www.chaojiying.com/price.html
        """
        params = {
            'codetype': codetype,
            'file_base64': base64_str
        }
        params.update(self.base_params)
        r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, headers=self.headers)
        return r.json()

    def ReportError(self, im_id):
        """
        im_id:报错题目的图片ID
        """
        params = {
            'id': im_id,
        }
        params.update(self.base_params)
        r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
        return r.json()


# 3.成功登录
if __name__ == '__main__':
    chaojiying = Chaojiying_Client('3148508410', '123456a', '935022')  # 用户中心>>软件ID 生成一个替换 96001
    im = open(code_path, 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
    result = chaojiying.PostPic(im, 1004)['pic_str']  # 1902 验证码类型  官方网站>>价格体系 3.4+版 print 后要加(),result存储识别结果
    # print chaojiying.PostPic(base64_str, 1902)  #此处为传入 base64代码
    driver.find_element(By.XPATH, '//*[@id="code"]').send_keys(result)  # 自动输入验证码
    time.sleep(7)
    driver.find_element(By.XPATH, '//*[@id="loginForm"]/div/div[5]/div/input[2]').click()  # 点击登录

# 4.获取最终课程信息
# ----------------------------------------课程信息↓------------------------------------------------------
# 爬虫获取信息
time.sleep(7)
course_list = []  # 课程列表
# 循环打开多个窗口
for page in range(1, 8):
    driver.execute_script("window.open('https://mooc.yit.edu.cn/user/index?kind=finish&page={}')".format(page))
    # 找出新窗口：
    new_window = driver.window_handles[page]  # '-1'代表打开的最后一个窗口
    # 切换到新窗口：
    driver.switch_to.window(new_window)
    response = driver.page_source  # 获取网页源代码
    tree = etree.HTML(response)  # xpath解析
    # 获取课程名称
    course_name = tree.xpath('/html/body/div[3]/div[2]/div[2]/div[1]/div[4]/div/div/div[2]/div[1]/a/text()')
    for c_name in course_name:
        if c_name not in course_list:
            course_list.append(c_name)
# 5.写入获取的课程信息
with open('./course.txt', 'w', encoding='utf-8') as fp:
    for i in course_list:
        fp.write(i)
        fp.write('\n')
print('写入完成，请查看当前目录下course.txt文件！')
# 关闭浏览器
time.sleep(10)  # 存留10秒后关闭
driver.quit()  # 关掉浏览器
